﻿// --------------------------------
// <copyright file="InlineList.cs" company="Faculty of Information Technology, Czech Technical University in Prague">
//     This document is shared by Microsoft Public License (MS-PL)
//     For further details please see http://msdn.microsoft.com/en-us/library/ff648068.aspx or license.txt.
// </copyright>
// <author>Lukáš Molnár</author>

// <email>molnaluk@fit.cvut.cz</email>

// <date>9. 11. 2011 22:22:38</date>

// <summary>
//
// </summary>
// --------------------------------
#if WINDOWS

using System.ComponentModel;
using System.Drawing.Design;
using FITClub.Episode1.Levels;

#endif

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input.Touch;
using FITClub.Util;

namespace FITClub.TextureMenu
{
#if WINDOWS

    [System.Serializable]
#endif
    public abstract class InlineList<T> : AMenuItemList<T>, IInlineList
    {
        #region Public properties

        [XmlAttribute]
#if WINDOWS
        [Category("Design")]
#endif
        public bool HideInactiveArrows { get; set; }

        [XmlElement]
#if WINDOWS
        [Category("Path")]
        [Editor(typeof(ContentPathEditor), typeof(UITypeEditor))]
        [EditorBrowsable(EditorBrowsableState.Always)]
#endif
        public string ArrowPath { get; set; }

        [XmlElement]
#if WINDOWS
        [Category("Design")]
#endif
        public Rectangle ArrowBounds { get; set; }

        [XmlIgnore]
#if WINDOWS
        [System.NonSerialized]
#endif
        public Texture2D ArrowTexture;

        [XmlIgnore]
        public bool HasValues { get { return this.Options != null && this.Options.Count > 0; } }

        [XmlIgnore]
        public T SelectedValue
        {
            get
            {
                if (this.SelectedIndex < 0)
                {
                    this.SelectedIndex = this.Options.Count + (this.SelectedIndex % (this.Options.Count + 1));
                }
                if (this.SelectedIndex >= this.Options.Count)
                {
                    this.SelectedIndex = this.SelectedIndex % this.Options.Count;
                }
                return this.Options[this.SelectedIndex];
            }
            set
            {
                int f = this.Options.IndexOf(value);
                if (f >= 0)
                {
                    this.SelectedIndex = f;
                }
                else
                {
                    this.Options.Add(value);
                    this.SelectedIndex = this.Options.Count - 1;
                }
            }
        }

        #endregion Public properties

        private bool valChanged;
        private int selIndex;

        /// <summary>
        /// Draw content of selected item
        /// </summary>
        /// <param name="spriteBatch"></param>
        /// <param name="tint"></param>
        internal abstract void DrawItem(SpriteBatch spriteBatch, Microsoft.Xna.Framework.Color tint);

        public override void Draw(SpriteBatch spriteBatch, Microsoft.Xna.Framework.Color tint)
        {
            base.Draw(spriteBatch, tint);

            DrawItem(spriteBatch, tint);

            if ((this.IsSelected || this.HideInactiveArrows == false) && this.IsEnabled)
            {
                spriteBatch.Draw(this.ArrowTexture, prevItemBounds, tint);

                Rectangle rect = prevItemBounds.OffsetXY(this.Bounds.Width, prevItemBounds.Height);
                spriteBatch.Draw(this.ArrowTexture, rect, null, tint, MathHelper.Pi, new Vector2(0, 0), SpriteEffects.None, 0);
            }
        }

        public override void Update(GameTime gt)
        {
#if WINDOWS_PHONE
            if (MenuManager.Current.ActualGestureSamples.Count > 0)
            {
                var drag = from itm in MenuManager.Current.ActualGestureSamples
                           where itm.GestureType == GestureType.HorizontalDrag
                           select itm.Delta;
                Vector2 deltaSum = Vector2.Zero;
                foreach (var item in drag)
                {
                    deltaSum += item;
                }
                int move = (int)deltaSum.X / (this.Bounds.Width / 3);
                if (move != 0)
                {
                    this.TraverseItems(move);
                    return;
                }
            }
#endif
            base.Update(gt);
        }

        private void Owner_MenuDeactivated(object sender, EventArgs e)
        {
            if (valChanged)
            {
                this.SelectedIndex = selIndex;
            }
        }

        private void Owner_MenuActivated(object sender, EventArgs e)
        {
            selIndex = this.SelectedIndex;
        }

        public void SettingsApplied()
        {
            valChanged = false;
        }

        public override void TraverseItems(int selectionMove)
        {
            base.TraverseItems(selectionMove);
            valChanged = true;
        }

        public override void LoadContent(Microsoft.Xna.Framework.Content.ContentManager loader)
        {
            if (ContentLoaded == false)
            {
                if (this.HasValues && this.Action != null && this.IgnoreParam == false) this.Action.Param = this.SelectedValue.ToString();
                this.ArrowTexture = loader.Load<Texture2D>(this.ArrowPath);
                if (ArrowBounds.Width == 0)
                {
                    ArrowBounds = new Rectangle(0, 0, this.Bounds.Height, this.Bounds.Height);
                }
                prevItemBounds = new Rectangle(this.Bounds.X + this.ArrowBounds.X, this.Bounds.Y + this.ArrowBounds.Y,
    this.ArrowBounds.Height, this.ArrowBounds.Height);
                nextItemBounds = prevItemBounds.OffsetXY(this.Bounds.Width - prevItemBounds.Width, 0);
                if (this.SelectionSound != null) this.SelectionSound.LoadContent(loader);
                this.ContentLoaded = true;
                this.Owner.MenuActivated += new EventHandler(Owner_MenuActivated);
                this.Owner.MenuDeactivated += new EventHandler(Owner_MenuDeactivated);
            }
        }

#if WINDOWS_PHONE == flase

        public override void Resized(double ratioX, double ratioY)
        {
            base.Resized(ratioX, ratioY);
            this.ArrowBounds = ArrowBounds.ScaleXY(ratioX, ratioY);
            prevItemBounds = new Rectangle(this.Bounds.X + this.ArrowBounds.X, this.Bounds.Y + this.ArrowBounds.Y,
                    this.ArrowBounds.Height, this.ArrowBounds.Height);
            nextItemBounds = prevItemBounds.OffsetXY(this.Bounds.Width - prevItemBounds.Width, 0);
        }

#endif

        public override void Dispose()
        {
            if (ContentLoaded)
            {
                if (this.SelectionSound != null) this.SelectionSound.Dispose();
                this.ArrowTexture.Dispose();
                this.ContentLoaded = false;
            }
        }
    }
}